package com.zzh.custom;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * @author zhangzhihao
 * @email zhangzhihao@gongjiangren.net
 * @date 2020-09-11
 * @desc
 */
public class FlowTextView extends View {


    // 文本内容的集合
    private List<String> mTextList;
    // 定义指定位置item背景色
    private Map<Integer, Integer> mColorBgIntMap;
    // 定义指定位置item字体颜色
    private Map<Integer, Integer> mColorItemIntMap;
    // 添加上下左右的值
    private float padding;
    private float paddingTop;
    private float paddingBottom;
    private float paddingLeft;
    private float paddingRight;
    // 添加背景值
    private int mBgColor = Color.GRAY;
    // 横向间隔
    private float mIntervalCross;
    // 竖向间隔
    private float mIntervalVertical;
    // 添加背景的圆角
    private float mRound;
    // 最多多少航 -1 不限制 不可以设置为0
    private int maxLines = -1;

    // 文本显示基础
    private float textSize;
    private int textColor = Color.BLACK;
    private Paint mBgPaint;
    private Paint mTextPaint;


    public FlowTextView(Context context) {
        this(context, null);
    }

    public FlowTextView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FlowTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        if (attrs != null) {
            TypedArray typeArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.FlowTextView, 0, 0);
            padding = typeArray.getDimension(R.styleable.FlowTextView_flowPadding, 0);
            paddingTop = typeArray.getDimension(R.styleable.FlowTextView_flowPaddingTop, padding);
            paddingBottom = typeArray.getDimension(R.styleable.FlowTextView_flowPaddingBottom, padding);
            paddingLeft = typeArray.getDimension(R.styleable.FlowTextView_flowPaddingLeft, padding);
            paddingRight = typeArray.getDimension(R.styleable.FlowTextView_flowPaddingRight, padding);
            mBgColor = typeArray.getColor(R.styleable.FlowTextView_flowItemBg, Color.GRAY);
            mIntervalCross = typeArray.getDimension(R.styleable.FlowTextView_flowIntervalCross, 5);
            mIntervalVertical = typeArray.getDimension(R.styleable.FlowTextView_flowIntervalVertical, 5);
            mRound = typeArray.getDimension(R.styleable.FlowTextView_flowRound, 0);
            textSize = typeArray.getDimensionPixelSize(R.styleable.FlowTextView_flowTextSize, 24);
            textColor = typeArray.getColor(R.styleable.FlowTextView_flowTextColor, Color.BLACK);
            maxLines = typeArray.getInteger(R.styleable.FlowTextView_maxLines, -1);
            typeArray.recycle();
        }
        mBgPaint = new Paint();
        mTextPaint = new Paint();
        mBgPaint.setAntiAlias(true);
        mTextPaint.setAntiAlias(true);
        mBgPaint.setColor(mBgColor);
        mTextPaint.setColor(textColor);
        mTextPaint.setTextSize(textSize);

        groupData("", "", false);
    }

    /**
     * 设置数据
     *
     * @param text     将要展示的内容
     * @param splitStr 内容拆分split值
     */
    public void setTexts(String text, String splitStr) {
        groupData(text, splitStr, false);
        requestLayout();
    }

    /**
     * 设置数据
     *
     * @param text            将要展示的内容
     * @param splitStr        内容拆分split值
     * @param mapBgColorInts  数据颜色单独配置 背景
     * @param colorItemIntMap 数据颜色单独配置 字体
     */
    public void setTexts(String text, String splitStr, Map<Integer, Integer> mapBgColorInts, Map<Integer, Integer> colorItemIntMap) {
        mColorBgIntMap = mapBgColorInts;
        mColorItemIntMap = colorItemIntMap;
        setTexts(text, splitStr);
    }

    /**
     * 添加数据
     *
     * @param strs 数据集合
     */
    public void setTexts(List<String> strs) {
        if (mTextList == null) {
            mTextList = new ArrayList<>();
        }
        mTextList.clear();
        if (strs == null || strs.size() <= 0) {
            requestLayout();
            return;
        }
        mTextList.addAll(strs);
        requestLayout();
    }

    /**
     * 添加数据
     *
     * @param strs            数据集合
     * @param mapBgColorInts  数据颜色单独配置 背景
     * @param colorItemIntMap 数据颜色单独配置 字体
     */
    public void setTexts(List<String> strs, Map<Integer, Integer> mapBgColorInts, Map<Integer, Integer> colorItemIntMap) {
        mColorBgIntMap = mapBgColorInts;
        mColorItemIntMap = colorItemIntMap;
        setTexts(strs);
    }

    /**
     * 添加数据
     *
     * @param strs 添加的集合
     */
    public void addTexts(List<String> strs) {
        if (mTextList == null) {
            mTextList = new ArrayList<>();
        }
        if (strs == null || strs.size() <= 0) {
            return;
        }
        mTextList.addAll(strs);
        requestLayout();
    }

    /**
     * 添加数据
     *
     * @param strs            添加的集合
     * @param mapBgColorInts  数据颜色单独配置 背景
     * @param colorItemIntMap 数据颜色单独配置 字体
     */
    public void addTexts(List<String> strs, Map<Integer, Integer> mapBgColorInts, Map<Integer, Integer> colorItemIntMap) {
        configAddColorMap(mapBgColorInts, colorItemIntMap);
        addTexts(strs);
    }

    private void configAddColorMap(Map<Integer, Integer> mapBgColorInts, Map<Integer, Integer> colorItemIntMap) {
        if (mColorBgIntMap == null) {
            mColorBgIntMap = mapBgColorInts;
        } else {
            if (mapBgColorInts == null) {
                mColorBgIntMap = null;
            } else {
                for (Integer integer : mapBgColorInts.keySet()) {
                    mColorBgIntMap.put(integer, mapBgColorInts.get(integer));
                }
            }
        }
        if (mColorItemIntMap == null) {
            mColorItemIntMap = colorItemIntMap;
        } else {
            if (colorItemIntMap == null) {
                colorItemIntMap = null;
            }
            for (Integer integer : colorItemIntMap.keySet()) {
                colorItemIntMap.put(integer, colorItemIntMap.get(integer));
            }
        }
    }

    /**
     * 添加数据
     *
     * @param text
     * @param splitStr
     */
    public void addTexts(String text, String splitStr) {
        groupData(text, splitStr, true);
        requestLayout();
    }

    /**
     * 添加数据
     *
     * @param text
     * @param splitStr
     * @param mapBgColorInts  数据颜色单独配置 背景
     * @param colorItemIntMap 数据颜色单独配置 字体
     */
    public void addTexts(String text, String splitStr, Map<Integer, Integer> mapBgColorInts, Map<Integer, Integer> colorItemIntMap) {
        configAddColorMap(mapBgColorInts, colorItemIntMap);
        groupData(text, splitStr, true);
        requestLayout();
    }


    private void groupData(String text, String splitStr, boolean isAdd) {
        if (mTextList == null) {
            mTextList = new ArrayList<>();
        }
        if (!isAdd) {
            mTextList.clear();
        }
        if (TextUtils.isEmpty(text) || TextUtils.isEmpty(splitStr)) {
            return;
        }
        String[] tests = text.split(splitStr);
        for (String test : tests) {
            if (!TextUtils.isEmpty(test.trim())) {
                mTextList.add(test);
            }
        }
    }

    private float textHeight;
    private float baseline;

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        int width = getMeasuredWidth();
        if (width == 0) {
            return;
        }
        float nowWidth = getPaddingLeft();
        float nowHeight = getPaddingTop();
        float actualWidth = width - getPaddingRight();
        float nowTextStartheight = nowHeight + paddingTop + textHeight;

        float omitLength = mTextPaint.measureText("...", 0, 3) + paddingLeft + paddingRight;
        int line = 1;
        boolean isPassiveEnd = false;
        for (int i = 0; i < mTextList.size(); i++) {
            configItemPaintColor(i);
            String itemStr = mTextList.get(i);
            float itemLength = mTextPaint.measureText(itemStr, 0, itemStr.length()) + paddingLeft + paddingRight;
            if (line == maxLines && mTextList.size() - 1 > i) {
                String itemNextStr = mTextList.get(i + 1);
                float itemNextLength = mTextPaint.measureText(itemNextStr, 0, itemNextStr.length()) + paddingLeft + paddingRight;
                if (itemLength + itemNextLength + omitLength + mIntervalCross * 2 > actualWidth - nowWidth) {
                    isPassiveEnd = true;
                }
            }
            if (itemLength > actualWidth - nowWidth) {
                line++;
                nowWidth = getPaddingLeft();
                nowHeight += mIntervalVertical + paddingTop + textHeight + paddingBottom;
                nowTextStartheight += mIntervalVertical + paddingTop + paddingBottom + textHeight;
            }
            // 绘制背景
            canvas.drawRoundRect(new RectF(nowWidth, nowHeight, nowWidth + itemLength, nowHeight + textHeight + paddingTop + paddingBottom), mRound, mRound, mBgPaint);
            // 绘制文字
            canvas.drawText(itemStr, nowWidth + paddingLeft, nowTextStartheight - textHeight + baseline, mTextPaint);
            nowWidth += mIntervalCross + itemLength;
            if (isPassiveEnd) {
                // 绘制背景
                canvas.drawRoundRect(new RectF(nowWidth, nowHeight, nowWidth + omitLength, nowHeight + textHeight + paddingTop + paddingBottom), mRound, mRound, mBgPaint);
                // 绘制文字
                canvas.drawText("...", nowWidth + paddingLeft, nowTextStartheight - textHeight + baseline, mTextPaint);
                break;
            }
        }
    }

    private void configItemPaintColor(int index) {
        if (mColorBgIntMap != null && mColorBgIntMap.containsKey(index)) {
            mBgPaint.setColor(mColorBgIntMap.get(index));
        } else {
            mBgPaint.setColor(mBgColor);
        }
        if (mColorItemIntMap != null && mColorItemIntMap.containsKey(index)) {
            mTextPaint.setColor(mColorItemIntMap.get(index));
        } else {
            mTextPaint.setColor(textColor);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(getMeasuredWidth(), measureHeight());
    }

    private int measureHeight() {
        if (getMeasuredWidth() == 0) {
            return 0;
        }
        int height = getPaddingTop() + getPaddingBottom();
        if (mTextList.size() <= 0) {
            return height;
        }
        if (mTextList.size() > 0) {
            Paint.FontMetrics fm = mTextPaint.getFontMetrics();
            baseline = -fm.ascent;
            textHeight = fm.descent - fm.ascent;
        }
        float nowWidth = getPaddingLeft();
        float nowHeight = 0;
        float actualWidth = getMeasuredWidth() - getPaddingRight();
        int count = 1;
        for (int i = 0; i < mTextList.size(); i++) {
            String itemStr = mTextList.get(i);
            float itemLength = mTextPaint.measureText(itemStr, 0, itemStr.length()) + paddingLeft + paddingRight;
            if (itemLength > actualWidth - nowWidth) {
                if (count >= maxLines) {
                    break;
                }
                count++;
                nowWidth = getPaddingLeft();
                nowHeight += mIntervalVertical + paddingTop + textHeight + paddingBottom;
            }
            nowWidth += mIntervalCross + itemLength;
        }
        nowHeight += textHeight + paddingTop + paddingBottom;
        height += nowHeight;
        return height;
    }
}
